package com.xhwy.service.impl;

import com.xhwy.entity.*;
import com.xhwy.mapper.*;
import com.xhwy.param.OrderDetailIdParam;
import com.xhwy.param.OrderParam;
import com.xhwy.param.ProductInventoryParam;
import com.xhwy.param.UserIdParam;
import com.xhwy.service.OrderService;
import com.xhwy.enums.OrderState;
import com.xhwy.util.PageUtil;
import com.xhwy.util.R;
import com.xhwy.util.UUIDUtil;
import com.xhwy.vo.OrderVo;
import com.xhwy.vo.ProductVo;
import com.xhwy.vo.ShoppingCartVo;
import com.xhwy.vo.admin.OrderDetailVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private AddressMapper addressMapper;
    @Autowired
    private UserMapper userMapper;

    /**
     * 生成订单业务
     *  1. 将购物车数据转成订单数据
     *  2. 进行订单数据的批量插入
     *  3. 商品库存修改
     *  4. 购物车数据清除
     *
     * @param orderParam
     * @return
     */
    @Transactional
    @Override
    public R save(OrderParam orderParam) {

        //准备数据
        List<Integer> shoppingCartIds = new ArrayList<>();
        List<ProductInventoryParam> productInventoryParams = new ArrayList<>();
        List<Order> orderList = new ArrayList<>();

        //生成数据
        Integer userId = orderParam.getUserId();
        //订单编号
        String orderDetailId = UUIDUtil.getUUID();
        //时间
        Timestamp timestamp = new Timestamp(new Date().getTime());
        //总付款
        Double totalPayment = 0.0;
        for (ShoppingCartVo cartVo: orderParam.getShoppingCartVos()){
            shoppingCartIds.add(cartVo.getShoppingCartId()); //购物车的编号
            //创建商品库存数据对象
            ProductInventoryParam inventoryParam = new ProductInventoryParam();
            inventoryParam.setProductId(cartVo.getProductId());
            inventoryParam.setNum(cartVo.getNum());
            //保存数据
            productInventoryParams.add(inventoryParam);

            //生成订单数据
            Order order = new Order();
            order.setOrderDetailId(orderDetailId);
            order.setProductId(cartVo.getProductId());
            order.setProductNumber(cartVo.getNum());
            //计算该商品的实付款
//            BigDecimal totalPaymentBigDecimal = new BigDecimal(totalPayment.toString());
            Double price = cartVo.getPromotionPrice() != null ? cartVo.getPromotionPrice(): cartVo.getMarketPrice();
//            BigDecimal priceBigDecimal = new BigDecimal(price.toString());
            //小计（单价 X 数量）
//            Double subTotal = priceBigDecimal.multiply(new BigDecimal(order.getProductNumber().toString())).doubleValue();
//            BigDecimal subTotalBigDecimal = new BigDecimal(subTotal.toString());
            order.setPrice(price);
            order.setCreateTime(timestamp);
            //添加到集合中
            orderList.add(order);

            //计算总价格
//            totalPayment = totalPaymentBigDecimal.add(subTotalBigDecimal).doubleValue();
            totalPayment += order.getPrice() * order.getProductNumber() ;
//            totalPayment = totalPaymentBigDecimal.doubleValue();
        }

        //生成订单详情数据
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderDetailId(orderDetailId);
        orderDetail.setAddressId(orderParam.getAddressId());
        orderDetail.setTitle("鲜花物语平台订单");
        orderDetail.setTotalPayment(totalPayment);
        orderDetail.setOrderState(OrderState.OBLIGATION.getStateCode());
        orderDetail.setUserId(userId);
        orderDetail.setCreateTime(timestamp);

        //提交订单数据
        orderDetailMapper.insert(orderDetail);
        orderMapper.batchInsert(orderList);
        //删除购物车数据
        shoppingCartMapper.batchDelete(shoppingCartIds);
        //修改商品库存和销量数据
        productMapper.batchUpdateInventoryAndSalesVolume(productInventoryParams);

        //查询创建的订单详情信息
        OrderDetail createdOrder = orderDetailMapper.getByOrderDetailId(orderDetailId);
        log.info("订单创建成功，订单数据==》" + createdOrder);
        return R.ok().put("data", createdOrder);
    }

    /**
     * 查询我的订单数据
     *
     * @param userIdParam 已经校验过的用户id
     * @return
     */
    @Override
    public R myOrder(UserIdParam userIdParam) {
        //根据用户id查询订单详情数据
        List<OrderDetail> orderDetailList = orderDetailMapper.getByUserId(userIdParam.getUserId());
        if(orderDetailList.size() < 1) return R.ok("订单数据查询成功").put("data", null);
        //转成以订单详情id为key的map集合
        Map<String, OrderDetail> orderDetailMap = orderDetailList.stream().collect(Collectors.toMap(OrderDetail::getOrderDetailId, v -> v));
        //订单详情id的Set集合
        Set<String> orderDetailIdSet = orderDetailMap.keySet();

        //根据订单详情id集合获取订单集合数据
        List<Order> orderList = orderMapper.getByOrderDetailIdCollection(orderDetailIdSet);

        //根据订单详情id对订单分组
        Map<String, List<Order>> orderMap = orderList.stream().collect(Collectors.groupingBy(Order::getOrderDetailId));

        //查询商品信息集合
        Set<Integer> productIdSet = orderList.stream().map(Order::getProductId).collect(Collectors.toSet());
        List<Product> productList = productMapper.getByProductIdCollection(productIdSet);
        //转换成map集合
        Map<Integer, Product> productMap = productList.stream().collect(Collectors.toMap(Product::getProductId, v -> v));

        //结果封装
        List<OrderVo> orderVoList = new ArrayList<>();

        for (String orderDetailId: orderMap.keySet()) {
            OrderVo orderVo = new OrderVo();

            //根据订单详情id获取map中的订单详情数据
            OrderDetail orderDetail = orderDetailMap.get(orderDetailId);
            //设置订单vo对象的数据
            orderVo.setOrderDetailId(orderDetailId);
            orderVo.setOrderState(orderDetail.getOrderState());
            orderVo.setCreateTime(orderDetail.getCreateTime());
            orderVo.setTotalPayment(orderDetail.getTotalPayment());
//            orderVo.setPaymentTime(orderDetail.getPaymentTime());

            //根据订单详情id获取map集合中的订单集合数据
            List<Order> orders = orderMap.get(orderDetailId);
            //获取订单vo对象里的商品vo集合
            if(orderVo.getProductVoList() == null) orderVo.setProductVoList(new ArrayList<>());
            List<ProductVo> productVoList = orderVo.getProductVoList();
            for (Order order: orders) {
                //创建商品vo对象
                ProductVo productVo = new ProductVo();
                //拷贝订单的属性值到商品vo的属性
                BeanUtils.copyProperties(order, productVo);
                //设置商品信息
                Product product = productMap.get(order.getProductId());
                productVo.setProductName(product.getProductName());
                productVo.setMainImage(product.getMainImage());

                //添加到集合中
                productVoList.add(productVo);
            }

            //添加到订单vo集合中
            orderVoList.add(orderVo);
        }

        //方式一：遍历获取
//        Set<String> orderDetailIds = new HashSet<>();
//        for (Order order : orders) {
//            orderDetailIds.add(order.getOrderDetailId());
//        }
//        //根据订单详情获取订单详情信息
//        List<OrderDetail> orderDetails = orderDetailMapper.getByOrderDetailIds(orderDetailIds);

        //方式二：使用集合的stream流
        //获取订单集合中的订单详情id生成set集合
//        Set<String> orderDetailIds = orders.stream().map(Order::getOrderDetailId).collect(Collectors.toSet());
//        //根据订单详情id集合获取订单详情信息集合
//        List<OrderDetail> orderDetails = orderDetailMapper.getByOrderDetailIds(orderDetailIds);
//
//        //获取商品数据
//        Set<Integer> productIds = orders.stream().map(Order::getProductId).collect(Collectors.toSet());
//        //根据商品id获取商品信息集合
//        List<Product> productList = productMapper.getByProductIds(productIds);
//
//        Map<Integer, Product> productMap = productList.stream().collect(Collectors.toMap(Product::getProductId, v -> v));
        //对集合进行排序
        Collections.sort(orderVoList);
        return R.ok("订单数据查询成功", orderVoList);
    }

    /**
     * 查询全部订单信息
     *
     * @return
     */
    @Override
    public PageUtil<com.xhwy.vo.admin.OrderVo> list(PageUtil<com.xhwy.vo.admin.OrderVo> pageUtil) {
        //获取订单详情信息
        List<OrderDetail> orderDetailList = orderDetailMapper.queryAllByLimit(pageUtil);
        int count = orderDetailMapper.count();
//        Map<String, OrderDetail> orderDetailMap = orderDetailList.stream().collect(Collectors.toMap(OrderDetail::getOrderDetailId, v -> v));
        //获取订单中的用户id集合
        Set<Integer> userIdSet = orderDetailList.stream().map(OrderDetail::getUserId).collect(Collectors.toSet());
        //根据用户id集合获取用户信息
        List<User> userList = userMapper.getByUserIdCollection(userIdSet);
        Map<Integer, User> userMap = userList.stream().collect(Collectors.toMap(User::getUserId, v -> v));

        //获取订单详情中的地址id
        Set<Integer> addressIdSet = orderDetailList.stream().map(OrderDetail::getAddressId).collect(Collectors.toSet());
        //根据地址id集合获取地址信息
        List<Address> addressList = addressMapper.getByAddressIdCollection(addressIdSet);
        Map<Integer, Address> addressMap = addressList.stream().collect(Collectors.toMap(Address::getAddressId, v -> v));

        List<com.xhwy.vo.admin.OrderVo> orderVoList = new ArrayList<>();
        for (OrderDetail orderDetail : orderDetailList) {
            com.xhwy.vo.admin.OrderVo orderVo = new com.xhwy.vo.admin.OrderVo();
            //将orderDetail对象的相同属性赋值给orderVo
            BeanUtils.copyProperties(orderDetail, orderVo);
            Address address = addressMap.get(orderDetail.getAddressId());
            orderVo.setContactsName(address.getContactsName());
            orderVo.setContactsPhone(address.getContactsPhone());
            String addressStr = address.getProvince() + address.getCity() + address.getDistrict() + address.getDetailAddress();
            orderVo.setAddress(addressStr);

            orderVo.setFounder(userMap.get(orderDetail.getUserId()).getUserName()); //订单创建者

            orderVoList.add(orderVo);
        }

        pageUtil.setCode("001");
        pageUtil.setList(orderVoList);
        pageUtil.setTotalRecords(count);
        return pageUtil;
    }

    /**
     * 根据订单详情id获取订单详情信息
     *
     * @param orderDetailIdParam 已经校验完成的订单详情id
     * @return
     */
    @Override
    public R orderDetail(OrderDetailIdParam orderDetailIdParam) {
        String orderDetailId = orderDetailIdParam.getOrderDetailId();
        //查询订单详情信息
        OrderDetail orderDetail = orderDetailMapper.getByOrderDetailId(orderDetailId);
        if(orderDetail == null) return R.fail("参数异常,查询失败");
        //获取地址信息
        Address address = addressMapper.getByAddressId(orderDetail.getAddressId());
        //获取用户信息
        String userName = userMapper.getUserNameByUserId(orderDetail.getUserId());
        //根据订单详情id获取订单信息
        List<Order> orderList = orderMapper.getByOrderDetailId(orderDetailId);
        //获取商品id集合
        Set<Integer> productIdSet = orderList.stream().map(Order::getProductId).collect(Collectors.toSet());
        //获取商品信息
        List<Product> productList = productMapper.getByProductIdCollection(productIdSet);
        Map<Integer, Product> productMap = productList.stream().collect(Collectors.toMap(Product::getProductId, v -> v));

        //创建orderDetailVo对象
        OrderDetailVo orderDetailVo = new OrderDetailVo();
        //将orderDetail相同的属性复制到orderDetailVo
        BeanUtils.copyProperties(orderDetail, orderDetailVo);
        //保存地址信息
        orderDetailVo.setAddress(address);
        //创建者
        orderDetailVo.setFounder(userName);
        //保存商品信息
        if(orderDetailVo.getProductVoList() == null) orderDetailVo.setProductVoList(new ArrayList<>());
        for (Order order:orderList) {
            ProductVo productVo = new ProductVo();
            Product product = productMap.get(order.getProductId());
            //拷贝相同属性
            BeanUtils.copyProperties(order, productVo);
            productVo.setProductName(product.getProductName());
            productVo.setMainImage(product.getMainImage());

            //添加到集合中
            orderDetailVo.getProductVoList().add(productVo);
        }

        return R.ok("订单详情查询成功").put("data", orderDetailVo);
    }
}
